package com.yanqu.road.entity.autodata.chuhan.data;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.FieldTypeAnnotation;
import com.yanqu.road.entity.autodata.AutoDataObject;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@FieldTypeAnnotation(tableName = "t_c_chuhan_user_data")
public class CrossChuHanUserData extends AutoDataObject {

    @FieldTypeAnnotation(desc = "活动ID", select = true, update = true)
    private int activityId;

    @FieldTypeAnnotation(desc = "活动分组ID", update = true)
    private int groupId;

    @FieldTypeAnnotation(desc = "玩家ID", update = true)
    private long userId;

    @FieldTypeAnnotation(desc = "商会ID，来自unionJoin")
    private String unionUid = "";
    @FieldTypeAnnotation(desc = "阵营，不为0才有资格")
    private int campId;

    @FieldTypeAnnotation(desc = "门客数据")
    private Map<Integer, CrossChuHanPatrons> patronsMap = new ConcurrentHashMap<>();
    @FieldTypeAnnotation(desc = "天赋加成带兵上限")
    private List<Long> soldierAddition = new ArrayList<>();

    @FieldTypeAnnotation(desc = "队伍数据")
    private Map<Integer, CrossChuHanTeam> teamMap = new ConcurrentHashMap<>();

    @FieldTypeAnnotation(desc = "兵营数据")
    private CrossChuHanBarracks barracks = new CrossChuHanBarracks();

    @FieldTypeAnnotation(desc = "npc事件重置时间")
    private long eventResetTime;
    @FieldTypeAnnotation(desc = "npc事件今日生成个数")
    private long eventTodayCount;
    @FieldTypeAnnotation(desc = "npc事件数据：位置，事件ID")
    private Map<Integer, Integer> eventMap = new ConcurrentHashMap<>();

    @FieldTypeAnnotation(desc = "被城主任命的职位，0没被任命")
    private int positionId;
    @FieldTypeAnnotation(desc = "累计了多少银两还没领")
    private Map<Long, BigInteger> posAddSilverMap = new ConcurrentHashMap<>();
    @FieldTypeAnnotation(desc = "上一次计算增加银两时间")
    private long posAddSilverTime;

    @FieldTypeAnnotation(desc = "战功")
    private long zhanGong;
    @FieldTypeAnnotation(desc = "战功变化时间")
    private long zhanGongTime;

    @FieldTypeAnnotation(desc = "求援时间")
    private long needHelpTime;

    @FieldTypeAnnotation(desc = "红点")
    private Map<Integer, Long> redDotMap = new ConcurrentHashMap<>();

    @FieldTypeAnnotation(desc = "马")
    private int horseId;

    @FieldTypeAnnotation(desc = "引导标志")
    private int guide;

    @FieldTypeAnnotation(desc = "累计(上缴/收取)职位银两")
    private BigInteger totalPosSilver = BigInteger.ZERO;
    ;

    @FieldTypeAnnotation(desc = "自选的重生点")
    private int birthCityId;
    @FieldTypeAnnotation(desc = "自选的时间")
    private long flitTime;
    @FieldTypeAnnotation(desc = "PVE战功cityType:zg")
    private Map<Integer, Long> pveZhanGongMap = new ConcurrentHashMap<>();
    @FieldTypeAnnotation(desc = "PVE战功变更时间cityType:time")
    private Map<Integer, Long> pveTimeMap = new ConcurrentHashMap<>();
    @FieldTypeAnnotation(desc = "请求Pve结果的时间")
    private long reqPveResultTime;
    @FieldTypeAnnotation(desc = "城市可收集辎重")
    private Map<Integer, Long> foodMap = new ConcurrentHashMap<>();
    @FieldTypeAnnotation(desc = "城市可收集兵符")
    private Map<Integer, Integer> bingFuMap = new ConcurrentHashMap<>();
    @FieldTypeAnnotation(desc = "结算的个人排名")
    private int userRank;

    // 不入库
    private long lastSyncPatronsTime;
    private long lastReqTime;

    // =============================

    public CrossChuHanUserData() {
    }

    public CrossChuHanUserData(int activityId, int groupId, long userId) {
        this.activityId = activityId;
        this.groupId = groupId;
        this.userId = userId;
        for (int i = 1; i <= 5; i++) {
            teamMap.put(i, new CrossChuHanTeam(userId, i));
        }
        this.horseId = 1;
        setInsertOption();
    }

    public int getActivityId() {
        return activityId;
    }

    public void setActivityId(int activityId) {
        if (this.activityId != activityId) {
            this.activityId = activityId;
            setOp(DataStatus.Update);
        }
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        if (this.userId != userId) {
            this.userId = userId;
            setOp(DataStatus.Update);
        }
    }

    public String getUnionUid() {
        return unionUid;
    }

    public void setUnionUid(String unionUid) {
        if (unionUid == null) {
            return;
        }
        if (this.unionUid == null || !this.unionUid.equals(unionUid)) {
            this.unionUid = unionUid;
            setOp(DataStatus.Update);
        }
    }

    public int getCampId() {
        return campId;
    }

    public void setCampId(int campId) {
        if (this.campId != campId) {
            this.campId = campId;
            setOp(DataStatus.Update);
        }
    }

    public Map<Integer, CrossChuHanPatrons> getPatronsMap() {
        return patronsMap;
    }

    public void setPatronsMap(Map<Integer, CrossChuHanPatrons> patronsMap) {
//        if (null == patronsMap) {
//            return;
//        }
//        Map<Integer, CrossChuHanPatrons> tempMap = new ConcurrentHashMap<>();
//        for (Object obj : patronsMap.values()) {
//            CrossChuHanPatrons data = null;
//            if (obj instanceof JSONObject) {
//                data = JSONObject.parseObject(obj.toString(), CrossChuHanPatrons.class);
//            } else {
//                data = (CrossChuHanPatrons) obj;
//            }
//            tempMap.put(data.getId(), data);
//        }

        this.patronsMap = patronsMap;
        setOp(DataStatus.Update);
    }

    public Map<Integer, CrossChuHanTeam> getTeamMap() {
        return teamMap;
    }

    public void setTeamMap(Map<Integer, CrossChuHanTeam> teamMap) {
//        if (null == teamMap) {
//            return;
//        }
//
//        Map<Integer, CrossChuHanTeam> tempMap = new ConcurrentHashMap<>();
//        for (Object obj : teamMap.values()) {
//            CrossChuHanTeam data = null;
//            if (obj instanceof JSONObject) {
//                data = JSONObject.parseObject(obj.toString(), CrossChuHanTeam.class);
//            } else {
//                data = (CrossChuHanTeam) obj;
//            }
//            tempMap.put(data.getOccupation(), data);
//        }

        this.teamMap = teamMap;
        setOp(DataStatus.Update);
    }

    public CrossChuHanBarracks getBarracks() {
        return barracks;
    }

    public void setBarracks(CrossChuHanBarracks barracks) {
        if (null == barracks) {
            return;
        }
        this.barracks = barracks;
        setOp(DataStatus.Update);
    }

    public long getEventResetTime() {
        return eventResetTime;
    }

    public void setEventResetTime(long eventResetTime) {
        if (this.eventResetTime != eventResetTime) {
            this.eventResetTime = eventResetTime;
            setOp(DataStatus.Update);
        }
    }

    public long getEventTodayCount() {
        return eventTodayCount;
    }

    public void setEventTodayCount(long eventTodayCount) {
        if (this.eventTodayCount != eventTodayCount) {
            this.eventTodayCount = eventTodayCount;
            setOp(DataStatus.Update);
        }
    }

    public Map<Integer, Integer> getEventMap() {
        return eventMap;
    }

    public void setEventMap(Map<Integer, Integer> eventMap) {
        if (null == eventMap) {
            return;
        }
        this.eventMap = eventMap;
        setOp(DataStatus.Update);
    }

    public int getPositionId() {
        return positionId;
    }

    public void setPositionId(int positionId) {
        if (this.positionId != positionId) {
            this.positionId = positionId;
            setOp(DataStatus.Update);
        }
    }

    public Map<Long, BigInteger> getPosAddSilverMap() {
        return posAddSilverMap;
    }

    public void setPosAddSilverMap(Map<Long, BigInteger> posAddSilverMap) {
        if (null == posAddSilverMap) {
            return;
        }
        this.posAddSilverMap = posAddSilverMap;
        setOp(DataStatus.Update);
    }

    public long getPosAddSilverTime() {
        return posAddSilverTime;
    }

    public void setPosAddSilverTime(long posAddSilverTime) {
        if (this.posAddSilverTime != posAddSilverTime) {
            this.posAddSilverTime = posAddSilverTime;
            setOp(DataStatus.Update);
        }
    }

    public long getZhanGong() {
        return zhanGong;
    }

    public void setZhanGong(long zhanGong) {
        if (this.zhanGong != zhanGong) {
            this.zhanGong = zhanGong;
            setOp(DataStatus.Update);
        }
    }

    public long getNeedHelpTime() {
        return needHelpTime;
    }

    public void setNeedHelpTime(long needHelpTime) {
        if (this.needHelpTime != needHelpTime) {
            this.needHelpTime = needHelpTime;
            setUpdateOption();
        }
    }

    public long getZhanGongTime() {
        return zhanGongTime;
    }

    public void setZhanGongTime(long zhanGongTime) {
        if (this.zhanGongTime != zhanGongTime) {
            this.zhanGongTime = zhanGongTime;
            setUpdateOption();
        }
    }

    public List<Long> getSoldierAddition() {
        return soldierAddition;
    }

    public void setSoldierAddition(List<Long> soldierAddition) {
        if (soldierAddition != null) {
            this.soldierAddition = soldierAddition;
            setUpdateOption();
        }
    }

    public Map<Integer, Long> getRedDotMap() {
        return redDotMap;
    }

    public void setRedDotMap(Map<Integer, Long> redDotMap) {
//        Map<Integer, Long> tempMap = new ConcurrentHashMap<>();
//        for (Integer cityType : redDotMap.keySet()) {
//            Object object = redDotMap.get(cityType);
//            if (object instanceof Integer) {
//                tempMap.put(cityType, Long.valueOf(object.toString()));
//            } else {
//                tempMap.put(cityType, (Long) object);
//            }
//        }
        this.redDotMap = redDotMap;
        setUpdateOption();
    }

    public int getHorseId() {
        return horseId;
    }

    public void setHorseId(int horseId) {
        if (this.horseId != horseId) {
            this.horseId = horseId;
            setUpdateOption();
        }
    }

    public int getGuide() {
        return guide;
    }

    public void setGuide(int guide) {
        if (this.guide != guide) {
            this.guide = guide;
            setUpdateOption();
        }
    }

    public BigInteger getTotalPosSilver() {
        return totalPosSilver;
    }

    public void setTotalPosSilver(BigInteger totalPosSilver) {
        if (null == totalPosSilver) {
            return;
        }
        if (!this.totalPosSilver.equals(totalPosSilver)) {
            this.totalPosSilver = totalPosSilver;
            setOp(DataStatus.Update);
        }
    }

    public int getGroupId() {
        return groupId;
    }

    public void setGroupId(int groupId) {
        if (this.groupId != groupId) {
            this.groupId = groupId;
            setUpdateOption();
        }
    }

    public int getBirthCityId() {
        return birthCityId;
    }

    public void setBirthCityId(int birthCityId) {
        this.birthCityId = birthCityId;
        setUpdateOption();
    }

    public long getFlitTime() {
        return flitTime;
    }

    public void setFlitTime(long flitTime) {
        this.flitTime = flitTime;
        setUpdateOption();
    }

    public Map<Integer, Long> getPveZhanGongMap() {
        return pveZhanGongMap;
    }

    public long getPveZhanGong(int cityType) {
        return pveZhanGongMap.getOrDefault(cityType, 0l);
    }

    public void setPveZhanGongMap(Map<Integer, Long> pveZhanGongMap) {
//        Map<Integer, Long> tempMap = new ConcurrentHashMap<>();
//        for (Integer cityType : pveZhanGongMap.keySet()) {
//            Object object = pveZhanGongMap.get(cityType);
//            if (object instanceof Integer) {
//                tempMap.put(cityType, Long.valueOf(object.toString()));
//            } else {
//                tempMap.put(cityType, (Long) object);
//            }
//        }
        this.pveZhanGongMap = pveZhanGongMap;
        setUpdateOption();
    }

    public Map<Integer, Long> getPveTimeMap() {
        return pveTimeMap;
    }

    public void setPveTimeMap(Map<Integer, Long> pveTimeMap) {
//        Map<Integer, Long> tempMap = new ConcurrentHashMap<>();
//        for (Integer cityType : pveTimeMap.keySet()) {
//            Object object = pveTimeMap.get(cityType);
//            if (object instanceof Integer) {
//                tempMap.put(cityType, Long.valueOf(object.toString()));
//            } else {
//                tempMap.put(cityType, (Long) object);
//            }
//        }
        this.pveTimeMap = pveTimeMap;
        setUpdateOption();
    }

    public long getPveTime(int cityType) {
        return pveTimeMap.getOrDefault(cityType, 0l);
    }

    public void addPveZhanGong(int cityType, long zhanGong, long battleTime) {
        synchronized (pveZhanGongMap) {
            long newZhanGong = getPveZhanGong(cityType) + zhanGong;
            pveZhanGongMap.put(cityType, newZhanGong);
            pveTimeMap.put(cityType, battleTime);
        }
        setUpdateOption();
    }

    public long getReqPveResultTime() {
        return reqPveResultTime;
    }

    public void setReqPveResultTime(long reqPveResultTime) {
        this.reqPveResultTime = reqPveResultTime;
        setUpdateOption();
    }

    public Map<Integer, Long> getFoodMap() {
        return foodMap;
    }

    public void setFoodMap(Map<Integer, Long> foodMap) {
//        Map<Integer, Long> tempMap = new ConcurrentHashMap<>();
//        for (Integer cityType : foodMap.keySet()) {
//            Object object = foodMap.get(cityType);
//            if (object instanceof Integer) {
//                tempMap.put(cityType, Long.valueOf(object.toString()));
//            } else {
//                tempMap.put(cityType, (Long) object);
//            }
//        }
        this.foodMap = foodMap;
        setUpdateOption();
    }

    public Map<Integer, Integer> getBingFuMap() {
        return bingFuMap;
    }

    public void setBingFuMap(Map<Integer, Integer> bingFuMap) {
        this.bingFuMap = bingFuMap;
        setUpdateOption();
    }

    // ============= 不入库 =============

    public long getLastSyncPatronsTime() {
        return lastSyncPatronsTime;
    }

    public void setLastSyncPatronsTime(long lastSyncPatronsTime) {
        this.lastSyncPatronsTime = lastSyncPatronsTime;
    }

    public long getLastReqTime() {
        return lastReqTime;
    }

    public void setLastReqTime(long lastReqTime) {
        this.lastReqTime = lastReqTime;
    }

    /**
     * 是否有可收集的
     * @return
     */
    public boolean haveCollect() {
        for (Long value : foodMap.values()) {
            if(value > 0) {
                return true;
            }
        }

        for (Integer value : bingFuMap.values()) {
            if(value > 0) {
                return true;
            }
        }

        return false;
    }

    public Set<Integer> getHaveCollectCity() {
        Set<Integer> result = new HashSet<>();

        for (Map.Entry<Integer, Long> entry : foodMap.entrySet()) {
            if(entry.getValue() > 0) {
                result.add(entry.getKey());
            }
        }

        for (Map.Entry<Integer, Integer> entry : bingFuMap.entrySet()) {
            if(entry.getValue() > 0) {
                result.add(entry.getKey());
            }
        }

        return result;
    }

    public long getFoodValue(Integer cityId) {
        return foodMap.getOrDefault(cityId, 0l);
    }

    public int getBingFuValue(Integer cityId) {
        return bingFuMap.getOrDefault(cityId, 0);
    }

    public long getAllFood() {
        long totalValue = 0;
        for (Long value : foodMap.values()) {
            totalValue += value;
        }
        return totalValue;
    }

    public int getAllBingFu() {
        int totalValue = 0;
        for (Integer value : bingFuMap.values()) {
            totalValue += value;
        }
        return totalValue;
    }

    public void addFood(int cityId, long productValue) {
        foodMap.put(cityId, foodMap.getOrDefault(cityId, 0l) + productValue);
        setUpdateOption();
    }

    public void addBingFu(int cityId, int productValue) {
        bingFuMap.put(cityId, bingFuMap.getOrDefault(cityId, 0) + productValue);
        setUpdateOption();
    }

    public int getUserRank() {
        return userRank;
    }

    public void setUserRank(int userRank) {
        this.userRank = userRank;
        setUpdateOption();
    }
}


